
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#include "mx509.h"
//Add by 081010
X509 * MX509_buildCertificateForClientWithoutServer(Credentials *credentials){
  X509_NAME *serverName   = X509_get_subject_name(credentials->middleCertificate);
  X509_NAME *issuerName   = X509_get_subject_name(credentials->middleCertificate);
  X509 *request           = X509_new();

  X509_set_version(request, 3);
  X509_set_subject_name(request, serverName);
  X509_set_issuer_name(request, issuerName);

  ASN1_INTEGER_set(X509_get_serialNumber(request), 1);
  X509_gmtime_adj(X509_get_notBefore(request), -365);
  X509_gmtime_adj(X509_get_notAfter(request), (long)60*60*24*365);
  X509_set_pubkey(request, credentials->leafKey);

  X509_sign(request, credentials->middleKey, EVP_md5());

  return request;
}
//end Add 081010
X509 * MX509_buildCertificateForClient(SSL *serverSession, Credentials *credentials) {
  X509 *serverCertificate = SSL_get_peer_certificate(serverSession);
  X509_NAME *serverName   = X509_get_subject_name(serverCertificate);
  X509_NAME *issuerName   = X509_get_subject_name(credentials->middleCertificate);
  X509 *request           = X509_new();

  X509_set_version(request, 3);
  X509_set_subject_name(request, serverName);
  X509_set_issuer_name(request, issuerName);

  ASN1_INTEGER_set(X509_get_serialNumber(request), 1);
  X509_gmtime_adj(X509_get_notBefore(request), -365);
  X509_gmtime_adj(X509_get_notAfter(request), (long)60*60*24*365);
  X509_set_pubkey(request, credentials->leafKey);

  X509_sign(request, credentials->middleKey, EVP_md5());

  return request;
}

EVP_PKEY * MX509_buildKeysForClient() {
  RSA *rsaKeyPair          = RSA_generate_key(1024, RSA_F4, NULL, NULL);
  EVP_PKEY *rsaKeyPairSpec = EVP_PKEY_new();
  
  EVP_PKEY_assign_RSA(rsaKeyPairSpec, rsaKeyPair);

  return rsaKeyPairSpec;
}


X509* MX509_loadCertificateFromFile(char* file) {
  SSL_CTX *context = SSL_CTX_new(SSLv23_server_method());
  SSL_CTX_use_certificate_file(context, file, SSL_FILETYPE_PEM);  

  return SSL_get_certificate(SSL_new(context));
}

EVP_PKEY* MX509_loadKeyFromFile(char* file) {
  SSL_CTX *context = SSL_CTX_new(SSLv23_server_method());
  SSL_CTX_use_PrivateKey_file(context, file, SSL_FILETYPE_PEM);

  return SSL_get_privatekey(SSL_new(context));
}
